#pragma once
#include "Header.h"
#include <queue>
#include <list>
#include <string>
#include <atomic>

class CFileFinder
{
private:
    std::queue<std::string> m_DirsQueue;
    std::atomic<unsigned int> m_nThreadCnt;
    std::atomic<unsigned int> m_nActiveThreadCnt;
    std::string m_strMatchFileName;
    CRITICAL_SECTION m_cs;
    std::list<std::string>* m_lpFileList;
    std::list<std::string>* m_lpDirList;
    HANDLE m_hSyncEvent;
    HANDLE m_hWaitEvent;
    BOOL m_bFullWordMatch;
    BOOL m_bInto;
    BOOL m_bSaveDir;

public:
    CFileFinder();
    ~CFileFinder();

protected:
    static DWORD WINAPI Adaptor(IN LPVOID lpParam);
    void SearchFileWorker();
    void CreateThreadAndWait();
    DWORD Search(IN std::string strDirName, IN std::string strFileName, OUT std::list<std::string>* lpFileList, OUT std::list<std::string>* lpDirList, IN BOOL bFullWordMatch, IN BOOL bInto);
    DWORD Search(IN const std::queue<std::string>& DirsQueue, IN std::string strFileName, OUT std::list<std::string>* lpFileList, OUT std::list<std::string>* lpDirList, IN BOOL bFullWordMatch, IN BOOL bInto);

public:
    static CFileFinder* GetInstance();
    static DWORD SearchFile(IN std::string strDirectoryName, IN std::string strFileName, OUT std::list<std::string>* lpFileList, IN BOOL bFullWordMatch, IN BOOL bInto);
    static DWORD SearchFile(IN const std::queue<std::string>& DirsQueue, IN std::string strFileName, OUT std::list<std::string>* lpFileList, IN BOOL bFullWordMatch, IN BOOL bInto);
    static DWORD TraverseDirectory(IN std::string strDirectoryName, OUT std::list<std::string>* lpFileList, OUT std::list<std::string>* lpDirList, IN BOOL bInto);
    static DWORD TraverseDirectory(IN const std::queue<std::string>& DirsQueue, OUT std::list<std::string>* lpFileList, OUT std::list<std::string>* lpDirList, IN BOOL bInto);
};
